home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #3 & #4
/
Amiga Plus CD - 1995 - No. 3 and 4.iso
/
pd
/
sound
/
cybersound
/
14bit.driver
/
source
/
asmsupport.asm
next >
Wrap
Assembly Source File
|
1995-07-20
|
5KB
|
230 lines
*****************************************************************************
*
* CyberSound: 14 Bit sound driver
*
* (c) 1995 by Christian Buchner
*
*****************************************************************************
*
* AsmSupport.asm
*
SECTION Code,CODE
* _CreateTable **************************************************************
; Parameters
; a0 = Table address
; (MUST have enough space for 65536 UWORDS)
; a1 = Additive Array
; 256 UBYTEs
;
; the table is organized as follows:
; 32768 UWORDS positive range, ascending order
; 32768 UWORDS negative range, ascending order
; access: (a0,d0.l*2)
; where d0.w is signed word sample data
; and the upper word of d0.l is *cleared!*
XDEF _CreateTable
_CreateTable movem.l a2/d2-d6,-(sp)
lea 128(a1),a2
move.l a2,a1 ; count the number of steps
moveq #128-1,d0 ; in the positive range
moveq #0,d5
.countpositive move.b (a1)+,d1
ext.w d1
ext.l d1
add.l d1,d5
dbra d0,.countpositive ; d5=number of steps
move.l #32768,d6 ; reset stretch counter
move.l a2,a1 ; middle value in calibdata
move.w #32768-1,d0 ; number of positive values -1
moveq #0,d1 ; HI value
moveq #0,d2 ; LO value
moveq #0,d3 ; counter
.fetchnext2 move.b (a1)+,d4 ; add calibtable to counter
ext.w d4
add.w d4,d3
.outerloop2 tst.w d3
bgt.s .positive2
.negative2 addq.w #1,d1 ; increment HI value
sub.w d4,d2 ; reset LO value
bra.s .fetchnext2
.positive2 move.b d1,(a0)+ ; store HI and LO value
move.b d2,(a0)+
sub.l d5,d6 ; stretch the table
bpl.s .repeat2 ; to 32768 entries
add.l #32768,d6
addq.w #1,d2 ; increment LO value
subq.w #1,d3 ; decrement counter
.repeat2 dbra d0,.outerloop2
move.l a2,a1 ; count the number of steps
moveq #128-1,d0 ; in the negative range
moveq #0,d5
.countnegative move.b -(a1),d1
ext.w d1
ext.l d1
add.l d1,d5
dbra d0,.countnegative ; d5=number of steps
move.l #32768,d6 ; reset stretch counter
add.l #2*32768,a0 ; place at the end of the table
move.l a2,a1 ; middle value in calibdata
move.w #32768-1,d0 ; number of negative values -1
moveq #-1,d1 ; HI value
moveq #-1,d2 ; LO value
moveq #0,d3 ; counter
.fetchnext1 move.b -(a1),d4 ; add calibtable to counter
ext.w d4
add.w d4,d3
add.w d4,d2 ; maximize LO value
.outerloop1 tst.w d3
bgt.s .positive1
.negative1 subq.w #1,d1
bra.s .fetchnext1
.positive1 move.b d2,-(a0) ; store LO and HI value
move.b d1,-(a0)
sub.l d5,d6 ; stretch the table
bpl.s .repeat1 ; to 32768 entries
add.l #32768,d6
subq.w #1,d2 ; decrement lo value
subq.w #1,d3 ; decrement counter
.repeat1 dbra d0,.outerloop1
movem.l (sp)+,a2/d2-d6
rts
* _ConvertStream *************************************************************
; Parameters
; a0=Stream pointer
; a1=MSB channel
; a2=LSB channel
; a3=Table address
; d0=samples
; d1=interleave
XDEF _ConvertStream
_ConvertStream movem.l d2/d3/d4/a2/a3,-(sp)
addq.w #1,d1 ; calc byte distance
add.w d1,d1 ; between 16 bit samples
moveq #0,d2 ; clear d2 LONGWORD
; This first loop minimizes access to chip RAM
; by creating ULONGs
move.w d0,-(sp) ; store samples
lsr.l #2,d0 ; calc samples/4
bra.s .convertentry ; enter loop
.convertHI swap d0
.convertLO move.w (a0),d2 ; get 16 bit data
add.w d1,a0 ; interleave
move.w (a3,d2.l*2),d3 ; get high/low byte
move.b d3,d4
rol.w #8,d4 ; shift left
; d3: ---- ---- 1111 ----
; d4: ---- ---- 1111 ----
move.w (a0),d2 ; get 16 bit data
add.w d1,a0 ; interleave
move.b (a3,d2.l*2),d3 ; get high byte
swap d3 ; swap ULONG
move.b 1(a3,d2.l*2),d4 ; get low byte
swap d4 ; swap ULONG
; d3: 1111 2222 ---- ----
; d4: 1111 2222 ---- ----
move.w (a0),d2 ; get 16 bit data
add.w d1,a0 ; interleave
move.w (a3,d2.l*2),d3 ; get high/low byte
move.b d3,d4
rol.w #8,d4
; d3: 1111 2222 3333 ----
; d4: 1111 2222 3333 ----
move.w (a0),d2 ; get 16 bit data
add.w d1,a0 ; interleave
move.b (a3,d2.l*2),d3 ; get high byte
move.l d3,(a1)+ ; store 4 high bytes
move.b 1(a3,d2.l*2),d4 ; get low byte
move.l d4,(a2)+ ; store 4 low bytes
; d3: 1111 2222 3333 4444
; d4: 1111 2222 3333 4444
.convertentry dbra d0,.convertLO ; loop back
swap d0
dbra d0,.convertHI
move.w (sp)+,d0 ; restore samples
and.w #$3,d0 ; calculate samples MOD 3
bra.s .restentry ; enter loop
.restLO move.w (a0),d2 ; get 16 bit data
add.w d1,a0 ; interleave
move.b (a3,d2.l*2),(a1)+ ; store high byte
move.b 1(a3,d2.l*2),(a2)+ ; store low byte
.restentry dbra d0,.restLO ; loop back
movem.l (sp)+,d2/d3/d4/a2/a3
rts
* _SwapEndian *****************************************************************
; Parameters
; a0=Table pointer
XDEF _SwapEndian
_SwapEndian movem.l d2/d3,-(sp)
move.w #65535,d0 ; loop 65536 UWORDs
moveq #0,d1 ; start offset = 0
.loop move.l d1,d2 ; calculate swap offset
rol.w #8,d2 ; swap big<->little endian
cmp.l d1,d2 ; only swap if one is lower
bhs.s .skip
move.w (a0,d1.l*2),d3 ; swap the table entries
move.w (a0,d2.l*2),(a0,d1.l*2)
move.w d3,(a0,d2.l*2)
.skip addq.l #1,d1 ; increment offset
dbra d0,.loop ; loop back
movem.l (sp)+,d2/d3
rts
******************************************************************************
END